//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================
#include <winhack.h>
#include "framebuffer.h"
//#include "sharemem.h"

void CFrameBuffer::Underlay_Overlay1BufferCopy_RGBT666()
{
    WORD *pDesBuffer;
    BYTE * pTransArray;
    DWORD *pOverlay1Buffer;

    WORD RGB_R, RGB_G, RGB_B;
    WORD SrcPixelRed, SrcPixelGreen, SrcPixelBlue;
    WORD BlendPixelRed, BlendPixelGreen, BlendPixelBlue;

    pOverlay1Buffer = (DWORD *)m_pOverlay1Fb;

    pTransArray = m_pTransArray + m_overlay1.PosX +
                    m_overlay1.PosY * m_screenWidth;

    pDesBuffer = (WORD *)m_pSurface->pixels +
                    (m_screenPosY + m_overlay1.PosY) *
                    m_mobileWidth + m_screenPosX +
                    m_overlay1.PosX;

    //Blend the pixel with desbuffer which has been setted by baseplane and overlay1 RGB
    for (int j = 0; j < m_overlay1.Height; j++) {
        for (int i = 0; i < m_overlay1.Width; i++) {
            if(0 == *pTransArray) {
                pTransArray++;
                pOverlay1Buffer++;
                pDesBuffer++;
                continue;
            }

            //Overlay1 Full Trans
            if((*pOverlay1Buffer & 0x3FFFF) == 0) {
                pTransArray++;
                pOverlay1Buffer++;
                pDesBuffer++;
                continue;
            }

            //Baseplane Full Trans
            if(*pDesBuffer == 0) {
                *pDesBuffer = ColorRGBT666ToRGB565(*pOverlay1Buffer);
                pTransArray++;
                pOverlay1Buffer++;
                pDesBuffer++;
                continue;
            }


            RGB_R = (WORD)(*pOverlay1Buffer & 0x3F000) >> 10;
            RGB_G = (WORD)(*pOverlay1Buffer & 0x000FC0) >> 4;
            RGB_B = (WORD)(*pOverlay1Buffer & 0x00003F) << 2;

            SrcPixelRed = (*pDesBuffer & 0xF800) >> 8;
            SrcPixelGreen = (*pDesBuffer & 0x07E0) >> 3;
            SrcPixelBlue = (*pDesBuffer & 0x001F) << 3;

            switch(m_nTransparencyKey) {
                case 0://8/8
                    BlendPixelRed = SrcPixelRed;
                    BlendPixelGreen = SrcPixelGreen;
                    BlendPixelBlue = SrcPixelBlue;
                    break;
                case 1://7/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 7/8)
                        + (RGB_R >> 3));
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 7/8)
                        + (RGB_G >> 3));
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 7/8)
                        + (RGB_B >> 3));
                    break;
                case 2://6/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 2/3)
                        + RGB_R * 1/3);
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 2/3)
                        + RGB_G * 1/3);
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 2/3)
                        + RGB_B * 1/3);
                    break;
                case 3://5/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 5/8)
                        + RGB_R * 3/8);
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 5/8)
                        + RGB_G * 3/8);
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 5/8)
                        + RGB_B * 3/8);
                    break;
                case 4://4/8
                    BlendPixelRed = (WORD)((SrcPixelRed >> 1)
                        + RGB_R  - (RGB_R >> 1));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 1)
                        + RGB_G  - (RGB_G >> 1));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 1)
                        + RGB_B  - (RGB_B >> 1));
                    break;
                case 5://3/8
                    BlendPixelRed = (WORD)(((SrcPixelRed >> 3) * 3)
                        + (RGB_R >> 3) * 5);
                    BlendPixelGreen = (WORD)(((SrcPixelGreen >> 3) * 3)
                        + (RGB_G >> 3) * 5);
                    BlendPixelBlue = (WORD)(((SrcPixelBlue >> 3) * 3)
                        + (RGB_B >> 3) * 5);
                    break;
                case 6://2/8
                    BlendPixelRed = (WORD)((SrcPixelRed >> 2)
                        + RGB_R  - (RGB_R >> 2));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 2)
                        + RGB_G  - (RGB_G >> 2));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 2)
                        + RGB_B  - (RGB_B >> 2));
                    break;
                case 7://1/8
                    // Improve efficiency
                default:
                    BlendPixelRed = (WORD)((SrcPixelRed >> 3)
                        + RGB_R  - (RGB_R >> 3));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 3)
                        + RGB_G  - (RGB_G >> 3));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 3)
                        + RGB_B  - (RGB_B >> 3));
                    break;
            }
            *pDesBuffer = ((BlendPixelRed & 0xF8) << 8) | ((BlendPixelGreen & 0xFC) << 3) | (BlendPixelBlue >> 3);

            pTransArray++;
            pOverlay1Buffer++;
            pDesBuffer++;
        }
        pTransArray += (m_screenWidth - m_overlay1.Width);
        pDesBuffer += (m_mobileWidth - m_overlay1.Width);
    }
}

void CFrameBuffer:: Underlay_Overlay1BufferCopy_RGB565()
{
    WORD *pDesBuffer;
    BYTE * pTransArray;
    WORD *pOverlay1Buffer;

    WORD RGB_R, RGB_G, RGB_B;
    WORD SrcPixelRed, SrcPixelGreen, SrcPixelBlue;
    WORD BlendPixelRed, BlendPixelGreen, BlendPixelBlue;

    pOverlay1Buffer = (WORD *)m_pOverlay1Fb;

    pTransArray = m_pTransArray + m_overlay1.PosX +
                    m_overlay1.PosY * m_screenWidth;

    pDesBuffer = (WORD *)m_pSurface->pixels +
                    (m_screenPosY + m_overlay1.PosY) *
                    m_mobileWidth + m_screenPosX +
                    m_overlay1.PosX;

    //Blend the pixel with desbuffer which has been setted by baseplane and overlay1 RGB
    for (int j = 0; j < m_overlay1.Height; j++) {
        for (int i = 0; i < m_overlay1.Width; i++) {
            if(0 == *pTransArray) {
                pTransArray++;
                pOverlay1Buffer++;
                pDesBuffer++;
                continue;
            }

            //Baseplane Full Trans
            if(*pDesBuffer == 0) {
                *pDesBuffer = *pOverlay1Buffer;
                pTransArray++;
                pOverlay1Buffer++;
                pDesBuffer++;
                continue;
            }

            RGB_R = (*pOverlay1Buffer & 0xF800) >> 8;
            RGB_G = (*pOverlay1Buffer & 0x07E0) >> 3;
            RGB_B = (*pOverlay1Buffer & 0x001F) << 3;

            SrcPixelRed = (*pDesBuffer & 0xF800) >> 8;
            SrcPixelGreen = (*pDesBuffer & 0x07E0) >> 3;
            SrcPixelBlue = (*pDesBuffer & 0x001F) << 3;

            switch(m_nTransparencyKey) {
                case 0://8/8
                    BlendPixelRed = SrcPixelRed;
                    BlendPixelGreen = SrcPixelGreen;
                    BlendPixelBlue = SrcPixelBlue;
                    break;
                case 1://7/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 7/8)
                        + (RGB_R >> 3));
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 7/8)
                        + (RGB_G >> 3));
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 7/8)
                        + (RGB_B >> 3));
                    break;
                case 2://6/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 2/3)
                        + RGB_R * 1/3);
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 2/3)
                        + RGB_G * 1/3);
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 2/3)
                        + RGB_B * 1/3);
                    break;
                case 3://5/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 5/8)
                        + RGB_R * 3/8);
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 5/8)
                        + RGB_G * 3/8);
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 5/8)
                        + RGB_B * 3/8);
                    break;
                case 4://4/8
                    BlendPixelRed = (WORD)((SrcPixelRed >> 1)
                        + RGB_R  - (RGB_R >> 1));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 1)
                        + RGB_G  - (RGB_G >> 1));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 1)
                        + RGB_B  - (RGB_B >> 1));
                    break;
                case 5://3/8
                    BlendPixelRed = (WORD)(((SrcPixelRed >> 3) * 3)
                        + (RGB_R >> 3) * 5);
                    BlendPixelGreen = (WORD)(((SrcPixelGreen >> 3) * 3)
                        + (RGB_G >> 3) * 5);
                    BlendPixelBlue = (WORD)(((SrcPixelBlue >> 3) * 3)
                        + (RGB_B >> 3) * 5);
                    break;
                case 6://2/8
                    BlendPixelRed = (WORD)((SrcPixelRed >> 2)
                        + RGB_R  - (RGB_R >> 2));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 2)
                        + RGB_G  - (RGB_G >> 2));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 2)
                        + RGB_B  - (RGB_B >> 2));
                    break;
                case 7://1/8
                    // Improve efficiency
                default:
                    BlendPixelRed = (WORD)((SrcPixelRed >> 3)
                        + RGB_R  - (RGB_R >> 3));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 3)
                        + RGB_G  - (RGB_G >> 3));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 3)
                        + RGB_B  - (RGB_B >> 3));
                    break;
            }
            *pDesBuffer = ((BlendPixelRed & 0xF8) << 8) | ((BlendPixelGreen & 0xFC) << 3) | (BlendPixelBlue >> 3);

            pTransArray++;
            pOverlay1Buffer++;
            pDesBuffer++;
        }
        pTransArray += (m_screenWidth - m_overlay1.Width);
        pDesBuffer += (m_mobileWidth - m_overlay1.Width);
    }
}

void CFrameBuffer::Overlay_Overlay1BufferCopy_RGBT666()
{
    WORD *pDesBuffer;
    DWORD *pOverlay1Buffer;

    WORD RGB_R, RGB_G, RGB_B;
    WORD SrcPixelRed, SrcPixelGreen, SrcPixelBlue;
    WORD BlendPixelRed, BlendPixelGreen, BlendPixelBlue;

    pOverlay1Buffer = (DWORD *)m_pOverlay1Fb;

    pDesBuffer = (WORD *)m_pSurface->pixels +
                    (m_screenPosY + m_overlay1.PosY) *
                    m_mobileWidth + m_screenPosX +
                    m_overlay1.PosX;

    //Blend the pixel with desbuffer which has been setted by baseplane and overlay1 RGB
    for (int j = 0; j < m_overlay1.Height; j++) {
        for (int i = 0; i < m_overlay1.Width; i++) {
            //No trans
            if((*pOverlay1Buffer >> 18) != 1) {
                *pDesBuffer = ColorRGBT666ToRGB565(*pOverlay1Buffer);
                pOverlay1Buffer++;
                pDesBuffer++;
                continue;
            }

            //Full trans
            if((*pOverlay1Buffer & 0x3FFFF) == 0) {
                pOverlay1Buffer++;
                pDesBuffer++;
                continue;
            }
            SrcPixelRed = (WORD)(*pOverlay1Buffer & 0x3F000) >> 10;
            SrcPixelGreen = (WORD)(*pOverlay1Buffer & 0x000FC0) >> 4;
            SrcPixelBlue = (WORD)(*pOverlay1Buffer & 0x00003F) << 2;

            RGB_R = (*pDesBuffer & 0xF800) >> 8;
            RGB_G = (*pDesBuffer & 0x07E0) >> 3;
            RGB_B = (*pDesBuffer & 0x001F) << 3;

            switch(m_nTransparencyKey) {
                case 0://8/8
                    BlendPixelRed = SrcPixelRed;
                    BlendPixelGreen = SrcPixelGreen;
                    BlendPixelBlue = SrcPixelBlue;
                    break;
                case 1://7/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 7/8)
                        + (RGB_R >> 3));
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 7/8)
                        + (RGB_G >> 3));
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 7/8)
                        + (RGB_B >> 3));
                    break;
                case 2://6/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 2/3)
                        + RGB_R * 1/3);
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 2/3)
                        + RGB_G * 1/3);
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 2/3)
                        + RGB_B * 1/3);
                    break;
                case 3://5/8
                    BlendPixelRed = (WORD)((SrcPixelRed * 5/8)
                        + RGB_R * 3/8);
                    BlendPixelGreen = (WORD)((SrcPixelGreen * 5/8)
                        + RGB_G * 3/8);
                    BlendPixelBlue = (WORD)((SrcPixelBlue * 5/8)
                        + RGB_B * 3/8);
                    break;
                case 4://4/8
                    BlendPixelRed = (WORD)((SrcPixelRed >> 1)
                        + RGB_R  - (RGB_R >> 1));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 1)
                        + RGB_G  - (RGB_G >> 1));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 1)
                        + RGB_B  - (RGB_B >> 1));
                    break;
                case 5://3/8
                    BlendPixelRed = (WORD)(((SrcPixelRed >> 3) * 3)
                        + (RGB_R >> 3) * 5);
                    BlendPixelGreen = (WORD)(((SrcPixelGreen >> 3) * 3)
                        + (RGB_G >> 3) * 5);
                    BlendPixelBlue = (WORD)(((SrcPixelBlue >> 3) * 3)
                        + (RGB_B >> 3) * 5);
                    break;
                case 6://2/8
                    BlendPixelRed = (WORD)((SrcPixelRed >> 2)
                        + RGB_R  - (RGB_R >> 2));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 2)
                        + RGB_G  - (RGB_G >> 2));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 2)
                        + RGB_B  - (RGB_B >> 2));
                    break;
                case 7://1/8
                    // Improve efficiency
                default:
                    BlendPixelRed = (WORD)((SrcPixelRed >> 3)
                        + RGB_R  - (RGB_R >> 3));
                    BlendPixelGreen = (WORD)((SrcPixelGreen >> 3)
                        + RGB_G  - (RGB_G >> 3));
                    BlendPixelBlue = (WORD)((SrcPixelBlue >> 3)
                        + RGB_B  - (RGB_B >> 3));
                    break;
            }
            *pDesBuffer = ((BlendPixelRed & 0xF8) << 8) | ((BlendPixelGreen & 0xFC) << 3) | (BlendPixelBlue >> 3);

            pOverlay1Buffer++;
            pDesBuffer++;
        }
        pDesBuffer += (m_mobileWidth - m_overlay1.Width);
    }
}

void CFrameBuffer::Overlay_Overlay1BufferCopy_RGB565()
{
    WORD *pDesBuffer;
    WORD *pOverlay1Buffer;

    pOverlay1Buffer = (WORD *)m_pOverlay1Fb;

    pDesBuffer = (WORD *)m_pSurface->pixels +
                    (m_screenPosY + m_overlay1.PosY) *
                    m_mobileWidth + m_screenPosX +
                    m_overlay1.PosX;

    for (int i = 0; i < m_overlay1.Height; i++) {
        memcpy((BYTE *)pDesBuffer, (BYTE *)pOverlay1Buffer,
            m_overlay1.Width * 2);
        pOverlay1Buffer += m_overlay1.Width;
        pDesBuffer += (m_mobileWidth - m_overlay1.Width);
    }
}

//When: 1. There has the overlap area(It's only mean three layer overlap)
//      2. There has transparence operation
//      3. Overlay2BufferCopy func has been completed
//      4. Overlay1BufferCopy func has not been done
//      5. Only support the baseplane RGBT555 now <--BUGBUG
void CFrameBuffer::Underlay_OverlapAreaOperation_Overlay1RGBT666()
{
    WORD *pDesBuffer;
    WORD *pBasePlaneBuffer;//RGBT555
    DWORD *pOverlay1Buffer;
    pDesBuffer = (WORD *)m_pSurface->pixels +
                    (m_screenPosY + m_overlapArea.PosY) *
                    m_mobileWidth + m_screenPosX +
                    m_overlapArea.PosX;

    pBasePlaneBuffer = (WORD *)m_bpBufferAddress + m_overlapArea.PosX +
                    m_overlapArea.PosY * m_screenWidth;

    pOverlay1Buffer = (DWORD *)m_pOverlay1Fb +
                    m_overlapArea.PosX - m_overlay1.PosX +
                    (m_overlapArea.PosY - m_overlay1.PosY) *
                    m_overlay1.Width;

    for(int j = 0; j < m_overlapArea.Height; j++) {
        for(int i = 0; i < m_overlapArea.Width; i++){
            if(*pBasePlaneBuffer >> 15){
                if(*pBasePlaneBuffer & 0x7FFF) {
                    if(((*pOverlay1Buffer >> 18) == 0) || (*pOverlay1Buffer & 0x3FFFF) != 0) {
                        *pDesBuffer = ColorRGBT555ToRGB565(*pBasePlaneBuffer);
                    }
                }//BUGBUG:If full trans, mix overlay1 and overlay2?
            }
            pDesBuffer++;
            pBasePlaneBuffer++;
            pOverlay1Buffer++;
        }
        pDesBuffer += (m_mobileWidth - m_overlapArea.Width);
        pBasePlaneBuffer += (m_screenWidth - m_overlapArea.Width);
        pOverlay1Buffer += (m_overlay1.Width - m_overlapArea.Width);
    }
}

//When: 1. There has the overlap area(It's only mean three layer overlap)
//      2. There has transparence operation
//      3. Overlay2BufferCopy func has been completed
//      4. Overlay1BufferCopy func has not been done
//      5. Only support the baseplane RGBT555 now <--BUGBUG
void CFrameBuffer::Underlay_OverlapAreaOperation_Overlay1RGB565()
{
    WORD *pDesBuffer;
    WORD *pBasePlaneBuffer;//RGBT555
    WORD *pOverlay1Buffer;
    pDesBuffer = (WORD *)m_pSurface->pixels +
                    (m_screenPosY + m_overlapArea.PosY) *
                    m_mobileWidth + m_screenPosX +
                    m_overlapArea.PosX;

    pBasePlaneBuffer = (WORD *)m_bpBufferAddress + m_overlapArea.PosX +
                    m_overlapArea.PosY * m_screenWidth;

    pOverlay1Buffer = (WORD *)m_pOverlay1Fb +
                    m_overlapArea.PosX - m_overlay1.PosX +
                    (m_overlapArea.PosY - m_overlay1.PosY) *
                    m_overlay1.Width;

    for(int j = 0; j < m_overlapArea.Height; j++) {
        for(int i = 0; i < m_overlapArea.Width; i++){
            if(*pBasePlaneBuffer >> 15){
                if(*pBasePlaneBuffer & 0x7FFF) {
                    *pDesBuffer = ColorRGBT555ToRGB565(*pBasePlaneBuffer);
                }
            }
            pDesBuffer++;
            pBasePlaneBuffer++;
            pOverlay1Buffer++;
        }
        pDesBuffer += (m_mobileWidth - m_overlapArea.Width);
        pBasePlaneBuffer += (m_screenWidth - m_overlapArea.Width);
        pOverlay1Buffer += (m_overlay1.Width - m_overlapArea.Width);
    }
}

void CFrameBuffer::SetOverlay1ColorFormat(ColorFormat CFormat)
{
    if (COLOR_RGB565 == CFormat) {
        m_nOverlay1PixelBytes = 2;
        if(m_bIsUnderlay) {
            m_pOverlay1BufferCopy = Underlay_Overlay1BufferCopy_RGB565;
        } else {
            m_pOverlay1BufferCopy = Overlay_Overlay1BufferCopy_RGB565;
        }
    }
    else if (COLOR_RGBT666 == CFormat) {
        m_nOverlay1PixelBytes = 4;
        if(m_bIsUnderlay) {
            m_pOverlay1BufferCopy = Underlay_Overlay1BufferCopy_RGBT666;
        } else {
            m_pOverlay1BufferCopy = Overlay_Overlay1BufferCopy_RGBT666;
        }
    }
    else {
        m_nOverlay1PixelBytes = 4;
        if(m_bIsUnderlay) {
            m_pOverlay1BufferCopy = Underlay_Overlay1BufferCopy_RGBT666;
        } else {
            m_pOverlay1BufferCopy = Overlay_Overlay1BufferCopy_RGBT666;
        }
    }
}

bool CFrameBuffer::SetOverlayYCbCr422(OverlayFormat *pOverlayFormat){
    if (pOverlayFormat->Width > m_mobileWidth
        || pOverlayFormat->Height > m_mobileHeight)
        return FALSE;

    int nYCbCrOverlayBufSize;

    nYCbCrOverlayBufSize =
        2 * pOverlayFormat->Width * pOverlayFormat->Height;
    // YCbCrOverlayBufferSize should be 4 bytes aligned
    if (nYCbCrOverlayBufSize & 0x3) {
        nYCbCrOverlayBufSize = (nYCbCrOverlayBufSize + 0x3) & (~0x3);
    }

    //m_pOverlay2Fb = realloc(m_pOverlay2Fb, nYCbCrOverlayBufSize);
    //if (!m_pOverlay2Fb) return FALSE;
    ECode ec = AllocShareMem(nYCbCrOverlayBufSize, MemoryProtection_RW,
                    (Address *)&m_pOverlay2Fb, NULL);
    if (NOERROR != ec) return FALSE;
    memset(m_pOverlay2Fb, 0, nYCbCrOverlayBufSize);

    memcpy(&m_overlay2, pOverlayFormat, sizeof(OverlayFormat));

    // Y Channel
    m_overlay2.pChannelFb[0] = m_pOverlay2Fb;
    m_overlay2.ChannelSize[0] = nYCbCrOverlayBufSize / 2;

    // Cb Channel
    m_overlay2.pChannelFb[1] =
                        (BYTE *)m_overlay2.pChannelFb[0] +
                        m_overlay2.ChannelSize[0];
    m_overlay2.ChannelSize[1] = nYCbCrOverlayBufSize / 4;

    // Cr Channel
    m_overlay2.pChannelFb[2] =
                        (BYTE *)m_overlay2.pChannelFb[1] +
                        m_overlay2.ChannelSize[1];
    m_overlay2.ChannelSize[2] = nYCbCrOverlayBufSize / 4;

    if(m_bIsUnderlay) {
        m_pOverlay2BufferCopy = Underlay_Overlay2BufferCopy_YCbCr422;
    } else {
        m_pOverlay2BufferCopy = Overlay_Overlay2BufferCopy_YCbCr422;
    }

    return true;
}

bool CFrameBuffer::SetOverlayYCbCr420(OverlayFormat *pOverlayFormat){
    if (pOverlayFormat->Width > m_mobileWidth
        || pOverlayFormat->Height > m_mobileHeight)
        return FALSE;

    int nYCbCrOverlayBufSize;

    nYCbCrOverlayBufSize =
        pOverlayFormat->Width * pOverlayFormat->Height * 3 / 2;
    // YCbCrOverlayBufferSize should be 4 bytes aligned
    if (nYCbCrOverlayBufSize & 0x3) {
        nYCbCrOverlayBufSize = (nYCbCrOverlayBufSize + 0x3) & (~0x3);
    }

        m_pOverlay2Fb = realloc(m_pOverlay2Fb, nYCbCrOverlayBufSize);
    if (!m_pOverlay2Fb) return FALSE;
    memset(m_pOverlay2Fb, 0, nYCbCrOverlayBufSize);

    memcpy(&m_overlay2, pOverlayFormat, sizeof(OverlayFormat));

    // Y Channel
    m_overlay2.pChannelFb[0] = m_pOverlay2Fb;
    m_overlay2.ChannelSize[0] = nYCbCrOverlayBufSize *2 / 3;

    // Cb Channel
    m_overlay2.pChannelFb[1] =
                        (BYTE *)m_overlay2.pChannelFb[0] +
                        m_overlay2.ChannelSize[0];
    m_overlay2.ChannelSize[1] = nYCbCrOverlayBufSize / 6;

    // Cr Channel
    m_overlay2.pChannelFb[2] =
                        (BYTE *)m_overlay2.pChannelFb[1] +
                        m_overlay2.ChannelSize[1];
    m_overlay2.ChannelSize[2] = nYCbCrOverlayBufSize / 6;

    if(m_bIsUnderlay) {
        m_pOverlay2BufferCopy = Underlay_Overlay2BufferCopy_YCbCr420;
    } else {
        m_pOverlay2BufferCopy = Overlay_Overlay2BufferCopy_YCbCr420;
    }

    return true;
}

BOOL GetTheoverlapArea()
{
    int Overlay1_Width = m_overlay1.Width;
    int Overlay1_Height = m_overlay1.Height;
    int Overlay1_PosX = m_overlay1.PosX;
    int Overlay1_PosY = m_overlay1.PosY;

    int Overlay2_Width = m_overlay2.Width;
    int Overlay2_Height = m_overlay2.Height;
    int Overlay2_PosX = m_overlay2.PosX;
    int Overlay2_PosY = m_overlay2.PosY;

    //If Overlap there is FALSE
    if((Overlay2_PosY + Overlay2_Height) < Overlay1_PosY ||
       (Overlay1_PosY + Overlay1_Height) < Overlay2_PosY ||
       (Overlay2_PosX + Overlay2_Width) < Overlay1_PosX ||
       (Overlay1_PosX + Overlay1_Width) < Overlay2_PosX) {
        return FALSE;
    }

    //There is the overlap area
    m_overlapArea.PosX =
        (Overlay1_PosX >= Overlay2_PosX) ? Overlay1_PosX : Overlay2_PosX;

    m_overlapArea.PosY =
        (Overlay1_PosY >= Overlay2_PosY) ? Overlay1_PosY : Overlay2_PosY;

    m_overlapArea.Width =
        (Overlay1_PosX + Overlay1_Width) <= (Overlay2_PosX + Overlay2_Width) ?
        (Overlay1_PosX + Overlay1_Width - m_overlapArea.PosX) :
        (Overlay2_PosX + Overlay2_Width - m_overlapArea.PosX);

    m_overlapArea.Height =
        (Overlay1_PosY + Overlay1_Height) <= (Overlay2_PosY + Overlay2_Height) ?
        (Overlay1_PosY + Overlay1_Height - m_overlapArea.PosY) :
        (Overlay2_PosY + Overlay2_Height - m_overlapArea.PosY);

    return TRUE;
}

